#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "stack.h"
#include "win32define.h"

const char *getLabelReserveSize (const char *name) {
    char *str = malloc(strlen(RESERVE_SIZE_SYM) + strlen(name) + 1) ;
    strcpy(str, RESERVE_SIZE_SYM) ;
    return strcat(str, name) ;
}

static struct LabelSymbol *G_LabelSyms = NULL ;

/* Ajoute un label avec la valeur correspondante. */
int pushLabelSymbol (const char *name, int value) {
    struct LabelSymbol *sym = malloc(sizeof(struct LabelSymbol)) ;
    if (sym == NULL) {
	return 1 ;
    }
    sym->label = strdup(name) ;
    sym->value = value ;
    sym->next = G_LabelSyms ;
    G_LabelSyms = sym ;
    return 0 ;
}

/* Tente de récupérer la valeur associé au label.
   Retourne 0 en cas de succès et associe la valeur à value,
   retourne 1 sinon.
*/
int getLabelValue (const char *label, int *value) {
    struct LabelSymbol *aux = G_LabelSyms ;
    int find = 0 ;
    while (aux != NULL && !find) {
	if (!strncmp(aux->label, label, strlen(aux->label))) {
	    find = 1 ;
	    *value = aux->value ;
	}
	aux = aux->next ;
    }
    if (!find) return 1 ;
    return 0 ;
}

#define MAX_LABEL_SIZE 200

/*
  Replace tous les labels dans le fichier correspondant à inputName, et écrit le tout dans le fichier
  correspondant à outputName.
  ATTENTION : inputName doit être différent de outputName
  ATTENTION : NE REMPLACE ACTUELLEMENT QUE LES LABELS EN FIN DE LIGNE !!!
*/
int replaceLabels (const char *inputName, const char *outputName) {
    FILE *input = fopen(inputName, "r"), *output = fopen(outputName, "w") ;
    char label[MAX_LABEL_SIZE] = {'_'};
    int value ;
    char c ;
    if (input == NULL || output == NULL) {
	return -1 ;
    }
    while ((c = fgetc(input)) != EOF) {
	if (c == '_') {
	    fgets(label+1, MAX_LABEL_SIZE-2, input) ;
	    if (!getLabelValue(label, &value)) {
		fprintf(output, "%d\n", value) ;
	    }
	    else {
		fputs(label, output) ;
	    }
	}
	else {
	    fputc(c, output) ;
	}
    }
    fclose(input) ;
    fclose(output) ;
    return 0 ;
}
